// uvm_tb/tests/binary_alu_base_test.sv
`ifndef BINARY_ALU_BASE_TEST_SV
`define BINARY_ALU_BASE_TEST_SV

class binary_alu_base_test extends uvm_test;

    // ========================================================================
    // UVM Macros
    // ========================================================================
    `uvm_component_utils(binary_alu_base_test)

    // ========================================================================
    // Test Components
    // ========================================================================
    binary_alu_env m_env;

    virtual binary_alu_if vif;

    // ========================================================================
    // Constructor
    // ========================================================================
    function new(string name = "binary_alu_base_test", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    // ========================================================================
    // UVM Build Phase
    // ========================================================================
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);

        // Create the environment
        m_env = binary_alu_env::type_id::create("m_env", this);

        // Get virtual interface handle from the config DB
        if (!uvm_config_db#(virtual binary_alu_if)::get(this, "", "vif", vif)) begin
            `uvm_fatal("NOVIF", "Virtual interface must be set for `uvm_test_top`")
        end

        uvm_config_db#(virtual binary_alu_if)::set(this, "m_env.m_agent.*", "vif", vif);
    endfunction

    // ========================================================================
    // UVM Connect Phase
    // ========================================================================
    virtual function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        // Connect the virtual interface to the agent
        // m_env.m_agent.vif = vif;
    endfunction

    // ========================================================================
    // UVM Run Phase
    // ========================================================================
    virtual task run_phase(uvm_phase phase);
        // Base test does nothing, will be extended by specific tests
    endtask

    virtual function void end_of_elaboration_phase(uvm_phase phase);
        uvm_top.print_topology();
    endfunction

endclass : binary_alu_base_test


// ============================================================================
// Test for Mode 0
// ============================================================================
class test_mode0 extends binary_alu_base_test;
    `uvm_component_utils(test_mode0)

    function new(string name = "test_mode0", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    virtual task run_phase(uvm_phase phase);
        seq_mode0_bypass seq;
        phase.raise_objection(this);
        seq = seq_mode0_bypass::type_id::create("seq");
        seq.start(m_env.m_agent.m_sequencer);

        // 等待足够的时间让 DUT 产生输出
        // DUT 可能有流水线延迟,需要更多时钟周期
        repeat (2) @(posedge vif.clk);  // 等待 2 个时钟上升沿

        phase.drop_objection(this);
    endtask
endclass

// ============================================================================
// Test for Mode 3
// ============================================================================
class test_mode3 extends binary_alu_base_test;
    `uvm_component_utils(test_mode3)

    function new(string name = "test_mode3", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    virtual task run_phase(uvm_phase phase);
        seq_mode3_dual_input seq;
        phase.raise_objection(this);
        seq = seq_mode3_dual_input::type_id::create("seq");
        seq.start(m_env.m_agent.m_sequencer);
        phase.drop_objection(this);
    endtask
endclass

`endif  // BINARY_ALU_BASE_TEST_SV
